#include<iostream>
#include<string>
#include<unistd.h>
#include<vector>
#include<pthread.h>

class Task {
private:
    int _x;
    int _y;
public:
    Task(int x, int y) : _x(x), _y(y) {}
    int Execute() {
        return _x + _y;
    }
};

class Result {
private:
    int _result;
    std::string _threadname;
public:
    Result(int result, std::string threadname) : _result(result), _threadname(threadname) {}
    void Print() {
        std::cout << _result << " threadname: " << _threadname << std::endl;
    }
    std::string threadname() {
        return _threadname;
    }
};

class threadData {
private:
    Task _t;
    std::string _threadname;
public:
    threadData(int x, int y, std::string threadname) : _t(x, y), _threadname(threadname) {}
    std::string threadname() {
        return _threadname;
    }
    int run() {
        return _t.Execute();
    }
};

void* handler(void* args) {
    threadData* td = static_cast<threadData*>(args);
    int result = td->run();
    std::string threadname = td->threadname(); 
    delete td; // 释放内存
    return new Result(result, threadname);
}

const int threadnum = 5;

int main() {
    std::vector<pthread_t> threads;
    std::vector<Result*> results;
    
    for(int i = 0; i < threadnum; i++) {
        char threadname[64];
        snprintf(threadname, sizeof(threadname), "thread-%d", i+1);
        
        pthread_t tid = 0;
        threadData* threaddata = new threadData(10, 20, threadname);
        
        if(pthread_create(&tid, nullptr, handler, threaddata) != 0) {
            std::cerr << "Failed to create thread" << std::endl;
            delete threaddata;
            continue;
        }
        
        threads.push_back(tid);
    }

    for(auto tid : threads) {
        void* ret = nullptr;
        pthread_join(tid, &ret);
        if(ret != nullptr) {
            results.push_back(static_cast<Result*>(ret));
        }
    }

    for(auto result : results) {
        if(result != nullptr) {
            result->Print();
            delete result;
        }
    }

    return 0;
}